import * as winston from 'winston';
import 'winston-daily-rotate-file';
import * as dayjs from 'dayjs';
import { DATE_FORMAT } from '@app/common';
import { utilities } from 'nest-winston';
import type { TransformableInfo } from 'logform';

export interface ITransformableInfo extends TransformableInfo {
  context?: string;
  ms?: string;
}

const winstonOptions = {
  levels: {
    error: 0,
    debug: 1,
    warn: 2,
    data: 3,
    info: 4,
    verbose: 5,
    silly: 6,
    custom: 7,
  },
  colors: {
    error: 'red',
    debug: 'blue',
    warn: 'yellow',
    info: 'green',
    data: 'magenta',
    verbose: 'cyan',
    silly: 'grey',
    custom: 'yellow',
  },
};

// custom log display format
const logFormat = winston.format.printf(
  ({ timestamp, level, stack, message }: ITransformableInfo) => {
    return `${timestamp} - [${level.toUpperCase().padEnd(7)}] - ${stack || message}`;
  },
);

const rotateFileDefault = {
  filename: 'application-%DATE%.log',
  datePattern: 'DD',
  dirname: `${process.cwd()}/logs/${dayjs().format('YYYYMM')}`,
  zippedArchive: true,
  maxSize: '20m',
  maxFiles: '14d',
  format: logFormat,
};
winston.addColors(winstonOptions.colors);

/**
 * 日志实例
 */
const winstonInstance = winston.createLogger({
  levels: winstonOptions.levels,
  exitOnError: false,
  format: winston.format.combine(
    winston.format.timestamp({
      format: DATE_FORMAT,
    }),
    winston.format.errors({ stack: true }),
    winston.format.splat(),
    winston.format.simple(),
  ),
  transports: [
    new winston.transports.Console({
      level: process.env.NODE_ENV === 'production' ? 'info' : 'info',
      format: winston.format.combine(
        utilities.format.nestLike(process.env.APP_NAME || 'CERTEASY', {
          colors: true,
          prettyPrint: true,
          processId: true,
          appName: true,
        }),
        winston.format.colorize({ all: true }),
      ),
    }),
    new winston.transports.DailyRotateFile(rotateFileDefault),
    new winston.transports.DailyRotateFile({
      ...rotateFileDefault,
      filename: 'error-%DATE%.log',
      level: 'error',
    }),
  ],
});

export const WinstonLogger = winstonInstance;
